let log = require('../../util/log.js');

module.exports = Card;
let colors = new Array("黑桃", "红桃", "梅花", "方片", "");
let values = new Array("3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2", "小王", "大王");

function Card(id) {
    this._id = id;
    this._color = Math.floor(id / 13);
    this._value = id % 13;

    if (this._color == 4)
        this._value += 13;

}

Card.prototype.getID = function () {
    return this._id;
}

Card.prototype.getValue = function () {
    return this._value;
}

Card.prototype.getColor = function () {
    return this._color;
}

Card.prototype.getName = function () {
    return colors[this._color] + values[this._value];
}

// 比较两张牌的大小
Card.compare = function (a, b) {

    if (a.getValue() < b.getValue())
        return -1;
    else
        return 1;
}
Card.sort = function (cardList) {
    return cardList.sort(Card.compare);
}
Card.cardType = {
    danpai: 1,
    duizi: 2,
    sanzhang: 3,
    sandai1: 4,
    sandai2: 5,
    sidai2: 6,
    zhadan: 7,
    shunzi: 8,
    liandui: 9,
    feiji: 10,
    wangzha: 11
}

Card.cardTypeName = ['错误', '单牌', '对子', '3张', '3带1', '3带对', '4带2', '炸弹', '顺子', '连队', '飞机', '王炸']

// 统计牌型数据
function getInfo(ls) {
    // 将1,2,3,4张的牌分开.
    // diff[0]记录单牌.
    // diff[1]记录对子....
    let diff = [[], [], [], []];
    let a = ls[0].getValue();
    let n = 0;
    // 不同牌的数量
    let sum = 1;

    for (let i = 1; i < ls.length; i++) {
        let v = ls[i].getValue();
        if (a != v) {
            diff[n].push(a);
            n = 0;
            sum++;
        }
        else
            n++;
        a = v;
    }
    diff[n].push(a);
    let info = [diff[0].length, diff[1].length, diff[2].length, diff[3].length];
    //返回统计信息
    return {'diff': diff, 'info': info, 'sum': sum};
}

let parse4 = function (ls) {
    let len = ls.length;

    // ls 已经排过序
    if (ls[0].getValue() == ls[len - 1].getValue()) {
        let c4 = [Card.cardType.danpai, Card.cardType.duizi, Card.cardType.sanzhang, Card.cardType.zhadan];
        return {id: c4[len - 1], base: ls[0].getValue()};
    }
    if (len == 4 && (ls[0].getValue() == ls[2].getValue() || ls[1].getValue() == ls[3].getValue())) {
        return {id: Card.cardType.sandai1, base: ls[1].getValue()};
    }

    if (len == 2 && ls[0].getColor() == 4 && ls[1].getColor() == 4)
        return {id: Card.cardType.wangzha, base: 100}; // 王炸
    return;

}
Card.shunzi = function (ss) {
    return shunzi(ss);
}

//判断顺子长度
function shunzi(ss) {
    let n = 0;
    let maxLen = 0;
    let x = ss[0];
    for (let i = 1; i < ss.length; i++) {
        if (x + 1 != ss[i] || ss[i] === 12) {
            if (n > maxLen) maxLen = n;
            n = 0;
        }
        else
            n++;
        x = ss[i];
    }
    if (n > maxLen) maxLen = n;
    log.d("shunzi count:", maxLen + 1);
    return maxLen + 1;
}
let parseMuti = function (ls) {
    // 检测带牌情况,带牌只能带一种, 要么是单牌, 要么是对子
    function checkExtra(info, xx, len) {
        let n = 0;
        let size1 = 0;
        let size0 = 0;
        for (let k in xx) {
            let i = xx[k];
            if (info[i] > 0) {
                size1 = info[i];
                size0 += info[i] * (i + 1);
                n++;
            }
        }
        if (size0 == len) return 0;
        if (size1 == len && n == 1) return 1;
        return -1;
    }

    let xx = getInfo(ls);
    let diff = xx.diff
    let info = xx.info;

    // 顺子
    if (xx.sum == ls.length) {
        if (xx.sum >= 5 && shunzi(diff[0]) == info[0]) {
            return {id: Card.cardType.shunzi, base: ls[0].getValue()}
        }
    }
    // 连队
    if (xx.sum == ls.length / 2) {
        //连队至少三对
        if (diff[1].length >= 3 && shunzi(diff[1]) == info[1])
            return {id: Card.cardType.liandui, base: ls[0].getValue()};
    }

    // 4+2(对子) 或者 4+2(单牌)
    if (info[3] == 1) {
        let n = checkExtra(info, [0, 1, 2], 2);
        //log.d('------',n);
        if (n < 0) return;
        else return {id: Card.cardType.sidai2, base: diff[3][0]};
    }
    // 飞机
    if (diff[2].length >= 2) {
        let len = shunzi(diff[2]);
        if (len < 2) return;
        // 如果算单张, 则全部算单张.
        let n = info[0] + info[1] * 2 + info[3] * 4 + (info[2] - len) * 3;

        //log.d('len n:',len,n);
        if (n == 0)
            return {id: Card.cardType.feiji, base: ls[0].getValue()};
        if (n == len) {
            log.d("带单飞");
            return {id: Card.cardType.feiji, base: diff[2][0]};
        }
        let size = checkExtra(info, [0, 1, 3], len);
        //log.d('len n size:',len,n,size);

        if (size < 0) return;		// 有杂牌
        else return {id: Card.cardType.feiji, base: diff[2][0]};
    }
    // 3+1
    if (info[2] == 1) {
        let n = checkExtra(info, [0, 1], 1);
        //log.d('aaaa',n,diff[2]);
        if (n == 1) return {id: Card.cardType.sandai2, base: diff[2][0]};
        else return;
    }
    return;
}
Card.count = function (ls) {
    return getInfo(ls);
}
Card.parseCardType = function (ls) {
    if (ls.length == 0)
        return null;

    ls.sort(Card.compare)
    ////log.d(ls);
    let typeId = 0;

    if (ls.length <= 4)
        typeId = parse4(ls)
    else
        typeId = parseMuti(ls);

    if (typeId) {
        //log.d('Card.cardTypeName:',Card.cardTypeName[typeId]);
        return {'typeId': typeId.id, base: typeId.base, 'cards': ls}
    }
}

let compare4 = function (a, b) {
    // 不用考虑王炸的情况,因为王炸后, 当前回合就结束了.
    // '单牌','对子','3张','4张' 的情况, 只需要比较第一张就可以了
    // 三带1的情况 比较第二张(牌型: aaab or bbba)
    if (a.cards.length == 4)
        return b.cards[1].getValue() > a.cards[1].getValue();
    else
        return b.cards[0].getValue() > a.cards[0].getValue();
}
// 比较两次出牌的大小
Card.compareCardType = function (a, b) {
    //log.d(a, b);

    if (a.typeId != b.typeId) {
        if (b.typeId == Card.cardType.wangzha)
            return true;
        if (b.typeId == Card.cardType.zhadan)
            return true;
        // 只有炸弹可以炸其它类型的牌
        log.e('出牌的类型不一致');
        return false;
    }
    if (a.cards.length != b.cards.length) {
        log.e('出牌的张数不一致');
        return false;
    }

    if (a.cards.length <= 4) {
        return compare4(a, b);
    }
    ////log.d('比牌:',b.cards[2].getValue(),a.cards[2].getValue());
    return b.cards[2].getValue() > a.cards[2].getValue();
}


